package com.touchX.display
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.media.SoundMixer;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	public class MusicRects extends Sprite
	{
		private static const SOUND_FILE:String = "../assets/bgMusic.mp3";
		private var isPlaying:Boolean;
		private var currentPosition:Number;
		private var _sound:Sound = new Sound();
		private var _channel:SoundChannel;
		private var _colorTransform:ColorTransform = new ColorTransform(.9, .9, .9);
		private var _filter:BlurFilter = new BlurFilter(4, 4);
		
		private var bars:Vector.<Bar>;
		private var _canvas:Bitmap;
		
		public function MusicRects()
		{
			super();
			this.buttonMode=true;
			bars=new Vector.<Bar>();
			var bar:Bar;
			for (var i:uint=0; i<8; i++) {
				bar = new Bar(0xffffff, false);
				bar.y = i * (Bar.LENGTH + Bar.MARGIN) + Bar.LENGTH; 
				bar.x = (Bar.LENGTH + Bar.MARGIN) * Bar.NUM_RECT;
				bars.unshift(bar);
			}
			_canvas = new Bitmap(new BitmapData(40, 50, true, 0xff000000));
			_canvas.rotation=90;
			addChild(_canvas);
			
			_sound.addEventListener(Event.COMPLETE, onLoadComplete);
			_sound.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
			_sound.load(new URLRequest(SOUND_FILE), new SoundLoaderContext(10000, true));
			
			this.addEventListener(MouseEvent.CLICK,switchMusic);
		}
		private function switchMusic(evt:MouseEvent):void{
			if(isPlaying) {
				currentPosition=_channel.position;
				_channel.stop();
			}else{
				_channel=_sound.play(currentPosition);
			}
			isPlaying=!isPlaying;
			
		}
		private function onLoadComplete(evt:Event):void{
			this.addEventListener(Event.ENTER_FRAME, loop);
			_channel = _sound.play(0, int.MAX_VALUE);
			_channel.addEventListener(Event.SOUND_COMPLETE,loopSound);
			isPlaying=true;
		}
		private function loopSound(evt:Event):void{
			_channel.removeEventListener(Event.SOUND_COMPLETE,loopSound);
			_channel= _sound.play(0, int.MAX_VALUE);
			_channel.addEventListener(Event.SOUND_COMPLETE,loopSound);
		}
		private function loop(evt:Event):void{
			var data:ByteArray = new ByteArray();
			var matrix:Matrix;
			var rect:Rectangle = new Rectangle(0, 0, _canvas.width, _canvas.height);
			var dp:Point = new Point(0, 0);
			
			_canvas.bitmapData.lock();
			
			SoundMixer.computeSpectrum(data, true);
			
			var d:Number = Math.max(_channel.rightPeak, _channel.leftPeak) * .2;
			_colorTransform.redMultiplier += (.5 - Math.random()) * d;
			_colorTransform.blueMultiplier += (.5 - Math.random()) * d;
			_colorTransform.greenMultiplier += (.5 - Math.random()) * d;
			_colorTransform.redMultiplier = Math.min(Math.max(_colorTransform.redMultiplier, .8), 1);
			_colorTransform.blueMultiplier = Math.min(Math.max(_colorTransform.blueMultiplier, .8), 1);
			_colorTransform.greenMultiplier = Math.min(Math.max(_colorTransform.greenMultiplier, .8), 1);
			_canvas.bitmapData.colorTransform(rect, _colorTransform);
			
			_canvas.bitmapData.applyFilter(_canvas.bitmapData, rect, dp, _filter);
			
			for (var i:uint=0; i<8; i++) {
				bars[i].setLevel(Math.sqrt((data.readFloat() + data.readFloat() + data.readFloat() + data.readFloat()) / 4));
				matrix = new Matrix();
				matrix.rotate(Math.PI)
				matrix.translate(bars[i].x, bars[i].y);
				_canvas.bitmapData.draw(bars[i], matrix);
			}
			
			
			_canvas.bitmapData.unlock();
		}
		private function onLoadError(evt:IOErrorEvent):void {
			trace("can not be loaded");
		}
	}
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
class Bar extends Sprite{
	public static const NUM_RECT:uint = 8;
	public static const LENGTH:uint = 3;
	public static const MARGIN:uint = 2;
	public static const MAX_LENGTH:uint = (LENGTH + MARGIN) * NUM_RECT - MARGIN;
	private var _rects:Vector.<Bitmap>;
	
	public function Bar(color:uint=0xffffff, gradient:Boolean=false){
		var r:uint = (color & 0x00ff0000) >> 16;
		var g:uint = (color & 0x0000ff00) >> 8;
		var b:uint = (color & 0x000000ff);
		
		_rects = new Vector.<Bitmap>;
		for (var i:uint = 0; i < NUM_RECT; i++){
			var grad:Number = Math.min(Math.sqrt((i+1)/NUM_RECT+.4), 1)
			var c:uint = (r*grad << 16) | (g*grad << 8) | b*grad;
			var bmp:Bitmap = new Bitmap(new BitmapData(LENGTH, LENGTH, false, gradient ? c : color));
			bmp.x = i * (LENGTH + MARGIN);
			_rects[i] = bmp;
			addChild(bmp);
			//bmp.visible = false;
		}
	}
	public function setLevel(level:Number):void {
		level = Math.min(NUM_RECT, Math.floor(NUM_RECT * level));
		for (var i:uint = 0; i<NUM_RECT; i++) {
			_rects[i].visible = i<level;
			
		}
	}
}
